package com.cz.video.framework.aspectj;

import cn.hutool.core.util.ObjectUtil;
import com.cz.video.common.annotation.LegalValidate;
import com.cz.video.common.constant.CommonConstants;
import com.cz.video.common.exception.ServiceException;
import com.cz.video.common.utils.ValidatorUtils;
import com.cz.video.common.utils.reflect.ReflectUtils;
import lombok.RequiredArgsConstructor;
import lombok.SneakyThrows;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.springframework.stereotype.Component;

import java.lang.reflect.Field;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;

/**
 * {@code @Description} : 内容合法校验切面
 * {@code @Author} : 陈智
 * {@code @Date}: 2023/7/20  14:58
 */
@Aspect
@Component
@RequiredArgsConstructor
public class LegalValidateAspect {

    private static final ThreadLocal<Map<String,Object>> threadLocal=new ThreadLocal<>();

    /**
     * 检查是否有违禁内容
     */
    @Before(value = "@annotation(legalValidate)")
    public void boBefore(JoinPoint joinPoint, LegalValidate legalValidate) throws IllegalAccessException {
        Object[] args = joinPoint.getArgs();
        Object target = null;
        boolean isLegal=true;
        //默认情况下校验所有参数
        if (legalValidate.value().length==0){
            for (Object arg : args) {
                if (!ValidatorUtils.validateLegalContent(arg)) {
                    isLegal=false;
                    target=arg;
                    break;
                }
            }
        }else {
            for (int i = 0; i < legalValidate.value().length; i++) {
                if (!ValidatorUtils.validateLegalContent(args[legalValidate.value()[i]])) {
                    isLegal = false;
                    target=args[legalValidate.value()[i]];
                    break;
                }
            }
        }

        if (!isLegal&&!legalValidate.isAllowInvoke()){
            //查找非法词列表
            List<String> illegalWords=ValidatorUtils.findIllegalWords(target);
            throw new ServiceException("内容中包含非法字符或敏感内容：" + illegalWords);
        }

        //记录到线程局部变量里，方便After使用
        HashMap<String, Object> map = new HashMap<>();
        map.put("target", target);
        map.put("isLegal", isLegal);
        threadLocal.set(map);

        //反射强制设置状态
        if (!isLegal&&legalValidate.isSetStatus()&&target!=null){
            Field status = ReflectUtils.getField(target.getClass(), "status");
            if(status!=null){
                status.setAccessible(true);
                status.set(target, CommonConstants.BANNED_STATUS);
            }
        }

    }


    /**
     * 处理完请求后执行
     *
     */
    @SneakyThrows
    @After(value = "@annotation(legalValidate)")
    public void doAfterReturning(LegalValidate legalValidate) {
        Object target = threadLocal.get().get("target");
        Boolean isLegal = (Boolean)threadLocal.get().get("isLegal");
        //如果合法，直接返回
        if (isLegal)return;

        //查找非法词列表
        List<String> illegalWords=ValidatorUtils.findIllegalWords(target);

            //记录到数据库中
        //注释掉了
//        if (legalValidate.isRecord()){
//
//            //设置属性
//            Field idFiled = ReflectUtils.getField(target.getClass(), "id");
//            idFiled.setAccessible(true);
//            SysContentAuditBo contentAuditBo = new SysContentAuditBo();
//            contentAuditBo.setIllegalContent(JsonUtils.toJsonString(illegalWords))
//                    .setUserId(Optional.ofNullable(LoginHelper.getUserId()).orElse(LoginHelper.getClientUserId()))
//                .setUserType(LoginHelper.getUserType().getUserType())
//                .setSourceId((Long) idFiled.get(target))
//                .setSourceType(SourceType.getType(target).getType());
//            if (ObjectUtil.isNotNull(contentAuditBo.getSourceId()))
//                contentAuditService.add(contentAuditBo);
//        }

        //抛出异常
        if (legalValidate.isThrowException())
            throw new ServiceException("内容中包含非法字符或敏感内容:"+illegalWords);
    }






}
